﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Timers;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using System.Windows;

using System.Runtime.InteropServices;

namespace LOL_Mastery_Tool
{
	public partial class BuildEditor : Form
	{
		static BuildEditor Editor;

		#region Setup Mastery Variables
		private static List<List<Mastery>> Masteries;
		private static List<List<Label>>   Labels;
		private static List<Mastery> offenseMasteries;
		private static List<Label>   offenseLabels;
		private static List<Mastery> defenseMasteries;
		private static List<Label>   defenseLabels;
		private static List<Mastery> utilityMasteries;
		private static List<Label>   utilityLabels;
		private static Point spacer;
		private static Point offense;
		private static Point defense;
		private static Point utility;
		private static List<Mastery> TreeMasteries;
		private static Mastery mOffense;
		private static Mastery mDefense;
		private static Mastery mUtility;
		private static List<Label> PointLabels;
		private static int PointsRemaining = 30;
		#region Offense Vars
		private static Mastery mDoubleEdgedSword;
		private static Mastery mFury;
		private static Mastery mSorcery;
		private static Mastery mButcher;
		private static Mastery mExposeWeakness;
		private static Mastery mBruteForce;
		private static Mastery mMentalForce;
		private static Mastery mFeast;
		private static Mastery mSpellWeaving;
		private static Mastery mMartialMastery;
		private static Mastery mArcaneMastery;
		private static Mastery mExecutioner;
		private static Mastery mBladeWeaving;
		private static Mastery mWarlord;
		private static Mastery mArchmage;
		private static Mastery mDangerousGame;
		private static Mastery mFrenzy;
		private static Mastery mDevestatingStrikes;
		private static Mastery mArcaneBlade;
		private static Mastery mHavoc;
		#endregion
		#region Defense Vars
		private static Mastery mBlock;
		private static Mastery mRecovery;
		private static Mastery mEnchantedArmor;
		private static Mastery mToughSkin;
		private static Mastery mUnyielding;
		private static Mastery mVeteranScars;
		private static Mastery mBladedArmor;
		private static Mastery mOppression;
		private static Mastery mJuggernaut;
		private static Mastery mHardiness;
		private static Mastery mResistance;
		private static Mastery mPerseverance;
		private static Mastery mSwiftness;
		private static Mastery mReinforcedArmor;
		private static Mastery mEvasive;
		private static Mastery mSecondWind;
		private static Mastery mTenacious;
		private static Mastery mRunicShield;
		private static Mastery mLegendaryGuardian;
		#endregion
		#region Utility Vars
		private static Mastery mPhasewalker;
		private static Mastery mFleetOfFoot;
		private static Mastery mMeditation;
		private static Mastery mScout;
		private static Mastery mSummonersInsight;
		private static Mastery mStrengthOfSpirit;
		private static Mastery mAlchemist;
		private static Mastery mGreed;
		private static Mastery mRunicAffinity;
		private static Mastery mVampirism;
		private static Mastery mCulinaryMaster;
		private static Mastery mScavenger;
		private static Mastery mWealth;
		private static Mastery mExpandedMind;
		private static Mastery mInspiration;
		private static Mastery mBandit;
		private static Mastery mIntelligence;
		private static Mastery mWanderer;
		#endregion
		#endregion

		#region Tooltip Variables
		private Mastery      tTipMastery        = new Mastery( "tTip" );
		private bool         tTipUp             = false;
		private Font         tTipFont           = new Font( "Microsoft Sans Serif", 8F );
		private string       tTipName           = "";
		private Font         tTipNameFont       = new Font( "Microsoft Sans Serif", 13F );
		private SolidBrush   tTipNameBrush      = new SolidBrush( Color.OrangeRed );
		private string       tTipRank           = "";
		private SolidBrush   tTipRankBrush      = new SolidBrush( Color.LimeGreen );
		private string       tTipReq            = "";
		private SolidBrush   tTipReqBrush       = new SolidBrush( Color.Red );
		private string       tTipLevelData      = "";
		private SolidBrush   tTipLevelDataBrush = new SolidBrush( Color.White );
		private Regex        tTipStringRegex    = new Regex( @"#\w{6}#.*#.*\r\n" );
		private Regex        tTipColorRegex     = new Regex( @"#\w{6}#" );
		private Regex        tTipNameRegex      = new Regex( @"\b#.*#" );
		private Regex        tTipTextRegex      = new Regex( @"\b:#.*\r\n" );
		private Regex        tTipLevelDataRegex = new Regex( @"%f" );
		private List<string> tTipColorText      = new List<string>();
		private List<string> tTipColors         = new List<string>();
		private List<string> tTipWhiteText      = new List<string>();
		#endregion

		private enum Trees { Offense, Defense, Utility }

		public static string Build_Name = "";
		public static string[] returnStrings;

		public BuildEditor()
		{
			InitializeComponent();
			setupData();
			// bgwChecker.RunWorkerAsync();
		}

		private void bgwChecker_DoWork(object sender, DoWorkEventArgs e)
		{
			int index = -1;
			int TreeMasteriesIndex = -1;
			List<Mastery> MasteryList = new List<Mastery>();
			List<Label>   LabelList = new List<Label>();
			while ( true )
			{
				foreach( List<Mastery> a in Masteries )
				{
					foreach ( Mastery m in a )
					{
						index = a.IndexOf( m );
						TreeMasteriesIndex = Masteries.IndexOf( a );
						#region Get Lists
						if ( a == offenseMasteries )
						{
							MasteryList = offenseMasteries;
							LabelList   = offenseLabels;
						} else if ( a == defenseMasteries ) {
							MasteryList = defenseMasteries;
							LabelList   = defenseLabels;
						} else if ( a == utilityMasteries ) {
							MasteryList = utilityMasteries;
							LabelList   = utilityLabels;
						}
						#endregion
						if( meetsRequirements( m ) == false || ( PointsRemaining == 0 && m.Level == 0 ) ) 
						{ 
							LabelList[index].ForeColor = Color.LightGray;
						} else if ( m.Level == m.MaxLevel ) {
							LabelList[index].ForeColor = Color.Orange;
						} else
						{
							LabelList[index].ForeColor = Color.LimeGreen;
						}
					}
				}
				Thread.Sleep( 200 );
			}
		}

		public static string[] showBox()
		{
			Editor = new BuildEditor();
			labelLists();
			Editor.buildLoad( "000000000000000000\r\n0000000000000000\r\n0000000000000000" );
			Editor.ShowDialog();
			Editor.BackColor = Color.White;
			return returnStrings;
		}

		public static string[] showBox( string name, string info, string buildPoints )
		{
			Editor = new BuildEditor();
			Editor.edtBuildName.Text   = name;
			Editor.edtDescription.Text = info;
			Editor.edtBuildCode.Text   = buildPoints;
			labelLists();
			Editor.buildLoad( buildPoints );
			Editor.ShowDialog();
			return returnStrings;
			//return Build_Name;
		}

		#region Event Handlers
		private void BuildEditor_FormClosing(object sender, FormClosingEventArgs e)
		{
			if ( e.CloseReason == CloseReason.UserClosing )
			{
				CancelClicked();
			}
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			CancelClicked();
		}

		private void btnAccept_Click(object sender, EventArgs e)
		{
			AcceptClicked();
		}

		private void button1_Click(object sender, EventArgs e)
		{
			Editor.buildLoad("00000000000000000000\r\n0000000000000000000\r\n000000000000000000");
		}

		private void edtBuildName_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Enter)
			{
				AcceptClicked();
			}
			if ( e.KeyCode == Keys.OemQuotes )
			{
				e.SuppressKeyPress = true;
			}
		}

		private void edtDescription_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Enter)
			{
				AcceptClicked();
			}
			if ( e.KeyCode == Keys.OemQuotes )
			{
				e.SuppressKeyPress = true;
			}
		}

		private void AcceptClicked()
		{
			returnStrings = new string[3]{ edtBuildName.Text, edtDescription.Text, edtBuildCode.Text };
			Editor.Dispose();
		}

		private void CancelClicked()
		{
			returnStrings = new string[1]{ "Cancel" };
			Editor.Dispose();
		}

		private void MasteryTree_MouseUp(object sender, MouseEventArgs e)
		{
			Point p = new Point( e.X, e.Y );
			bool b = false;
			int index = -1;
			int TreeMasteriesIndex = -1;
			Mastery treeOBJ = null;
			List<Mastery> MasteryList = new List<Mastery>();
			List<Label>   LabelList = new List<Label>();
			foreach( List<Mastery> a in Masteries )
			{
				foreach ( Mastery m in a )
				{
					if ( m.Rectangle.Contains( p ) )
					{
						index = a.IndexOf( m );
						TreeMasteriesIndex = Masteries.IndexOf( a );
						#region Get Lists
						if ( a == offenseMasteries )
						{
							MasteryList = offenseMasteries;
							LabelList   = offenseLabels;
							treeOBJ     = mOffense;
						} else if ( a == defenseMasteries ) {
							MasteryList = defenseMasteries;
							LabelList   = defenseLabels;
							treeOBJ     = mDefense;
						} else if ( a == utilityMasteries ) {
							MasteryList = utilityMasteries;
							LabelList   = utilityLabels;
							treeOBJ     = mUtility;
						}
						#endregion
						if ( PointsRemaining > 0 && meetsRequirements( MasteryList[index] ) && MasteryList[index].Level < MasteryList[index].MaxLevel && e.Button == MouseButtons.Left )
						{
							MasteryList[index].Level += 1;
							TreeMasteries[TreeMasteriesIndex].Level += 1;
							PointLabels[TreeMasteriesIndex].Text = PointLabels[TreeMasteriesIndex].Tag + TreeMasteries[TreeMasteriesIndex].Level.ToString();
							PointsRemaining -= 1;
							Editor.lblPointsRemaining.Text = Editor.lblPointsRemaining.Tag + PointsRemaining.ToString();
							LabelList[index].Text = MasteryList[index].Level.ToString() + " / " + LabelList[index].Tag.ToString();
							updateBuildCode();
						} else if ( PointsRemaining < 30 && MasteryList[index].Level > 0 && e.Button == MouseButtons.Right && wontAffectOtherMasteries( m ) ) {
							MasteryList[index].Level -= 1;
							TreeMasteries[TreeMasteriesIndex].Level -= 1;
							PointLabels[TreeMasteriesIndex].Text = PointLabels[TreeMasteriesIndex].Tag + TreeMasteries[TreeMasteriesIndex].Level.ToString();
							PointsRemaining += 1;
							Editor.lblPointsRemaining.Text = Editor.lblPointsRemaining.Tag + PointsRemaining.ToString();
							LabelList[index].Text = MasteryList[index].Level.ToString() + " / " + LabelList[index].Tag.ToString();
							updateBuildCode();
						}
						if ( m == tTipMastery ) { tooltip( m ); }
						b = true;
						break;
					}
				}
				if ( b ) break;
			}
		}

		private void MasteryTree_MouseMove(object sender, MouseEventArgs e)
		{
			foreach( List<Mastery> a in Masteries )
			{
				foreach ( Mastery m in a )
				{
					if ( m.Rectangle.Contains( e.Location ) )
					{
						if ( tTipUp == false ) // && tTipMastery != m ) 
						{
							tooltip( m );
						}
					} else  {
						if ( tTipMastery == m ) 
						{
							tTipUp = false;
							pnlTooltip.Visible = false;
						}
					}
				}
			}
		}

		private void tooltip( Mastery m )
		{
			tTipMastery = m;
			#region Name
			tTipName = m.Name;
			if     ( getTreeMastery( m ) == mOffense ) { tTipNameBrush = new SolidBrush( Color.FromArgb( 255, 69, 0 ) ); }
			else if( getTreeMastery( m ) == mDefense ) { tTipNameBrush = new SolidBrush( Color.DeepSkyBlue ); }
			else if( getTreeMastery( m ) == mUtility ) { tTipNameBrush = new SolidBrush( Color.GreenYellow ); }
			#endregion
			#region Rank
			tTipRank = "Rank: " + m.Level.ToString() + "/" + m.MaxLevel.ToString() ;
			if     ( ( PointsRemaining == 0 && m.Level == 0 ) || !meetsRequirements( m ) ) { tTipRankBrush = new SolidBrush( Color.LightGray ); }
			else if( (m.Level / m.MaxLevel) < 1 )                                          { tTipRankBrush = new SolidBrush( Color.LimeGreen ); } 
			else                                                                           { tTipRankBrush = new SolidBrush( Color.Orange    ); }
			#endregion
			#region Requirements
			int i = 0;
			tTipReq = "";
			foreach( Mastery m2 in m.Conditions )
			{
				tTipReq += "Requires " + m.ConditionLevels[i].ToString() + " points in " + m2.Name + ".\r\n";
				i++;
			}
			tTipReq.TrimEnd( "\r\n".ToCharArray() );
			#endregion
			#region Build Data
			if ( tTipStringRegex.IsMatch( m.LevelData ) )
			{
				tTipLevelData = "";
				tTipColorText = new List<string>();
				tTipColors    = new List<string>();
				tTipWhiteText = new List<string>();
				MatchCollection MC = tTipStringRegex.Matches( m.LevelData );
				foreach ( Match match in MC )
				{
					//MessageBox.Show( "Color: " + color.Match( match.Value ).Value.Trim( '#' ) + "\r\nName: " + name.Match( match.Value ).Value.Trim( '#' ) + "\r\nText: " + text.Match( match.Value ).Value.TrimStart( ":# ".ToCharArray() ) );
					tTipColors   .Add( tTipColorRegex.Match( match.Value ).Value.Trim( '#' ) );
					tTipColorText.Add( tTipNameRegex .Match( match.Value ).Value.Trim( '#' ) );
					tTipWhiteText.Add( tTipTextRegex .Match( match.Value ).Value.TrimStart( ":# ".ToCharArray() ) );
				}
			} else {
				if ( tTipLevelDataRegex.IsMatch(m.LevelData) )
				{
					string s = m.LevelData;
					int i2 = 0;
					foreach ( Match mtch in tTipLevelDataRegex.Matches( s ) )
					{
						string r = "";
						for ( int i3 = 0; i3 < m.MaxLevel; i3++ )
						{
							r += m.DataReplace[i2,i3].ToString();
							if ( i3 != m.MaxLevel - 1 ) { r += " / "; }
						}
						s = tTipLevelDataRegex.Replace( s, r, 1, 0 );
						i2++;
					}
					tTipLevelData = s;
				} else {
					tTipLevelData = m.LevelData;
				}
			}
			#endregion
			#region Panel Size
			pnlTooltip.Width  = m.Width;
			pnlTooltip.Height = m.Height;
			#endregion
			pnlTooltip.Location = getToolTipPoint( m );
			pnlTooltip.Invalidate();
			pnlTooltip.Visible = true;
			tTipUp = true;
		}

		private void pnlTooltip_Paint(object sender, PaintEventArgs e)
		{
			Graphics g = e.Graphics;
			float x = 0;
			float x2 = 0;
			float y = 0;
			SolidBrush b;
			g.Clear( Color.Black );
			g.DrawRectangle(new Pen(Brushes.LightGray, 1), new Rectangle(e.ClipRectangle.X + 3, e.ClipRectangle.Y + 3, e.ClipRectangle.Width - 6, e.ClipRectangle.Height - 6));
			g.DrawString( tTipName, tTipNameFont, tTipNameBrush, new PointF( 4.5F,  5.0F ) );
			g.DrawString( tTipRank,     tTipFont, tTipRankBrush, new PointF( 5.0F, 25.0F ) );
			g.DrawString(  tTipReq,     tTipFont,  tTipReqBrush, new PointF( 5.0F, 37.0F ) );
			if ( tTipReq == "" ) { y = 38F; } else { y = 38F + g.MeasureString( tTipReq, tTipFont ).Height; }
			if ( tTipLevelData == "" )
			{
				x  = 5F;
				g.DrawString( "Improves the following Summoner Spells:", tTipFont, tTipLevelDataBrush, x, y );
				y += 12F;
				if ( tTipMastery == mDoubleEdgedSword ) { x2 = 50; } else if ( tTipMastery == mBlock ) { x2 = 50; } else if ( tTipMastery == mPhasewalker ) { x2 = 75; }
				for ( int i = 0; i < tTipColors.Count; i++ ) 
				{
					b = new SolidBrush( ColorTranslator.FromHtml( "#" + tTipColors[i] ) );
					g.DrawString( tTipColorText[i], tTipFont, b, x, y );
					//x += g.MeasureString( tTipColorText[i], tTipFont ).Width;
					g.DrawString( tTipWhiteText[i], tTipFont, tTipLevelDataBrush, x2, y );
					y += 12F;
					x = 5F;
				}
			} else {
				g.DrawString( tTipLevelData, tTipFont, tTipLevelDataBrush, 5F, y );
			}
		}

		private void pnlTooltip_MouseMove(object sender, MouseEventArgs e)
		{
			tTipUp = false;
			pnlTooltip.Visible = false;
		}
		#endregion

		/// <summary>
		/// Sets up all the mastery data needed for tooltips, clicking, and positioning.
		/// </summary>
		private static void setupData()
		{
			Masteries = new List<List<Mastery>>();
			offenseMasteries = new List<Mastery>();
			defenseMasteries = new List<Mastery>();
			utilityMasteries = new List<Mastery>();
			Labels = new List<List<Label>>();
			offenseLabels = new List<Label>();
			defenseLabels = new List<Label>();
			utilityLabels = new List<Label>();
			spacer  = new Point(  64, 70 );
			offense = new Point(  22, 14 );
			defense = new Point( 295, 14 );
			utility = new Point( 568, 14 );
			TreeMasteries = new List<Mastery>();
			mOffense = new Mastery( "Offense" );
			mDefense = new Mastery( "Defense" );
			mUtility = new Mastery( "Utility" );
			TreeMasteries.Add( mOffense );
			TreeMasteries.Add( mDefense );
			TreeMasteries.Add( mUtility );
			Mastery[] offensePoints = new Mastery[] { mOffense };
			Mastery[] defensePoints = new Mastery[] { mDefense };
			Mastery[] utilityPoints = new Mastery[] { mUtility };
			#region Offensive
			#region Double-Edged Sword
			mDoubleEdgedSword =  
						new Mastery
						( 
							"Double-Edged Sword", 
							treePoint(0,0,Trees.Offense),
							1,
							(
								"#FFFF00#Melee:# Deal an additional 2% damage\r\n" +
								"and receive an additional 1% damage\r\n" +
								"#FFFF00#Ranged:# Deal an additional 1.5%\r\n" +
								"damage and receive an additional 1.5%\r\n" + 
								"damage\r\n"
							),
							null,
							null,
							null,
							0,
							390,
							105
						);
				#endregion
				#region Fury
				mFury = new Mastery(
					"Fury",
					treePoint(1, 0, Trees.Offense),
					4,
					"+%f Attack Speed",
					new double[,] { { 1.25, 2.5, 3.75, 5} },
					null,
					null,
					0,
					200,
					60);
				#endregion
				#region Sorcery
				mSorcery =
					new Mastery(
						"Sorcery",
						treePoint(2, 0, Trees.Offense),
						4,
						"+%f% Cooldown Reduction",
						new double[,] { { 1.25, 2.5, 3.75, 5 } },
						null,
						null,
						0,
						200,
						60);
				#endregion
				#region Butcher
				mButcher =
					new Mastery(
						"Butcher",
						treePoint(3, 0, Trees.Offense),
						1,
						"Basic attacks and single target spells\r\n" +
						"deal an additional 2 bonus damage to minions\r\n" + 
						"and monsters\r\n\r\n" + 
						"This does not trigger off of area of effect\r\n" +
						"damage or damage over time effects",
						null,
						null,
						null,
						0,
						330,
						60);
				#endregion
				#region Expose Weakness
				mExposeWeakness =
					new Mastery(
						"Expose Weakness",
						treePoint(0, 1, Trees.Offense),
						1,
						"Damage an enemy with a spell\r\n" +
						"increases allied champions' damage to\r\n" +
						"that enemy by 1% for the next 3 seconds",
						null,
						offensePoints,
						new int[] { 4 },
						1,
						300,
						85);
				#endregion
				#region Brute Force
				mBruteForce =
					new Mastery
					(
						"Brute Force",
						treePoint(1, 1, Trees.Offense),
						3,
						"+%f Attack Damage at level 18 (+%f\r\n" + "Attack Damage per level)",
						new double[,] { { 4, 7, 10 }, { 0.22, 0.39, 0.55 } },
						offensePoints,
						new int[] { 4 },
						1,
						200,
						60
					);
				#endregion
				#region Mental Force
				mMentalForce =
					new Mastery(
						"Mental Force",
						treePoint(2, 1, Trees.Offense),
						3,
						"+%f Ability Power at level 18 (+%f\r\n" + "Ability Power per level",
						new double[,] { { 6, 11, 16  }, { 0.33, 0.61, 0.89 } },
						offensePoints,
						new int[] { 4 },
						1,
						200,
						60);
				#endregion
				#region Feast
				mFeast =
					new Mastery(
						"Feast",
						treePoint(3, 1, Trees.Offense),
						1,
						"Killing a unit restores 2 Health and 1\r\n" + "Mana",
						null,
						new Mastery[] { mOffense, mButcher }, 
						new int[] { 4, 1 },
						1,
						275,
						82);
				#endregion
				#region Spell Weaving
				mSpellWeaving =
					new Mastery(
						"Spell Weaving",
						treePoint(0, 2, Trees.Offense),
						1,
						"Damaging an enemy champion with a\r\n" + "Basic Attack increases Spell Damage\r\n" + "by 1%, stacking up to 3 times (max 3%\r\n" + "damage increase)",
						null,
						offensePoints,
						new int[] { 8 },
						2,
						275,
						82);
				#endregion
				#region Martial Mastery
				mMartialMastery =
					new Mastery(
						"Martial Mastery",
						treePoint(1, 2, Trees.Offense),
						1,
						"+5 Attack Damage",
						null,
						new Mastery[] { mOffense, mBruteForce }, 
						new int[] { 8, 3 },
						2,
						275,
						82);
				#endregion
				#region Arcane Mastery
				mArcaneMastery =
					new Mastery(
						"Arcane Mastery",
						treePoint(2, 2, Trees.Offense),
						1,
						"+8 Ability Power",
						null,
						new Mastery[] { mOffense, mMentalForce }, 
						new int[] { 8, 3 },
						2,
						275,
						82);
				#endregion
				#region Executioner
				mExecutioner =
					new Mastery(
						"Executioner",
						treePoint(3, 2, Trees.Offense),
						3,
						"Increases damage dealt to champions\r\n" + "below %f% by 5%",
						new double[,] { { 20, 35, 50 } },
						offensePoints,
						new int[] { 8 },
						2,
						230,
						70);
				#endregion
				#region Blade Weaving
				mBladeWeaving =
					new Mastery(
						"Blade Weaving",
						treePoint(0, 3, Trees.Offense),
						1,
						"Damaging an enemy champion with a\r\n" + "spell increases Basic Attack Damage\r\n" + "by 1%, stacking up to 3 times (max 3%\r\n" + "damage increase)\r\n\r\n" + "This cannot trigger more than once a\r\n" + "second",
						null,
						new Mastery[] { mOffense, mSpellWeaving },
						new int[] { 12, 1 },
						3,
						200,
						85);
				#endregion
				#region Warlord
				mWarlord =
					new Mastery(
						"Warlord",
						treePoint(1, 3, Trees.Offense),
						3,
						"Increases bonus Attack Damage by %f%",
						new double[,] { { 2, 3.5, 5 } }, 
						offensePoints,
						new int[] { 12 },
						3,
						200,
						85);
				#endregion
				#region Archmage
				mArchmage =
					new Mastery(
						"Archmage",
						treePoint(2, 3, Trees.Offense),
						3,
						"Increases bonus Ability Power by %f%",
						new double[,] { { 2, 3.5, 5 } },
						offensePoints,
						new int[] { 12 },
						3,
						200,
						85);
				#endregion
				#region Dangerous Game
				mDangerousGame =
					new Mastery(
						"Dangerous Game",
						treePoint(3, 3, Trees.Offense),
						1,
						"Killing a champion restores 5% missing\r\n" + "Health and Mana",
						null, 
						new Mastery[] { mOffense, mExecutioner }, 
						new int[] { 12, 3 },
						3,
						200,
						85);
				#endregion
				#region Frenzy
					mFrenzy =
						new Mastery(
							"Frenzy",
							treePoint(0, 4, Trees.Offense),
							1,
							"Critical hits grant +5% Attack Speed for\r\n" + "3 seconds (stacks up to 3 times)",
							null,
							offensePoints,
							new int[] { 16 },
							4,
							200,
							85);
				#endregion
				#region Devestating Strikes
					mDevestatingStrikes =
						new Mastery(
							"Devestating Strikes",
							treePoint(1, 4, Trees.Offense),
							3,
							"+%f% Armor and Magic Penetration",
							new double[,] { { 2, 4, 6 } }, 
							offensePoints,
							new int[] { 16 },
							4,
							200,
							85);
				#endregion
				#region Arcane Blade
					mArcaneBlade =
						new Mastery(
							"Arcane Blade",
							treePoint(3, 4, Trees.Offense),
							1,
							"Basic Attacks also deal bonus magic damage equal to 5% of Ability Power",
							null,
							offensePoints,
							new int[] { 16 },
							4,
							260,
							70);
				#endregion
				#region Havoc
					mHavoc =
						new Mastery(
							"Havoc",
							treePoint(1, 5, Trees.Offense),
							1,
							"+3% Increased Damage",
							null,
							offensePoints,
							new int[] { 20 },
							5,
							305,
							75);
				#endregion
				#region Add Items to Lists
					offenseMasteries.Add(mDoubleEdgedSword);
					offenseMasteries.Add(mFury);
					offenseMasteries.Add(mSorcery);
					offenseMasteries.Add(mButcher);
					offenseMasteries.Add(mExposeWeakness);
					offenseMasteries.Add(mBruteForce);
					offenseMasteries.Add(mMentalForce);
					offenseMasteries.Add(mFeast);
					offenseMasteries.Add(mSpellWeaving);
					offenseMasteries.Add(mMartialMastery);
					offenseMasteries.Add(mArcaneMastery);
					offenseMasteries.Add(mExecutioner);
					offenseMasteries.Add(mBladeWeaving);
					offenseMasteries.Add(mWarlord);
					offenseMasteries.Add(mArchmage);
					offenseMasteries.Add(mDangerousGame);
					offenseMasteries.Add(mFrenzy);
					offenseMasteries.Add(mDevestatingStrikes);
					offenseMasteries.Add(mArcaneBlade);
					offenseMasteries.Add(mHavoc);
					Masteries.Add(offenseMasteries);
				#endregion
			#endregion
			#region Defensive
					#region Block
					mBlock =
						new Mastery
						(
							"Block",
							treePoint(0, 0, Trees.Defense),
							2,
							(
								"Reduces incoming damage from\r\n" + "champion basic attacks by %f"
							),
							new double[,] { { 1,2 } }, 
							null,
							null,
							0,
							427,
							105
						);
					#endregion
					#region Recovery
					mRecovery =
						new Mastery
						(
							"Recovery",
							treePoint(1, 0, Trees.Defense),
							2,
							"+%f Health per 5 seconds",
							new double[,] { { 1, 2 } },
							null,
							null,
							0,
							200,
							60
						);
					#endregion
					#region Enchanted Armor
					mEnchantedArmor =
						new Mastery(
							"Enchanted Armor",
							treePoint(2, 0, Trees.Defense),
							2,
							"Increases bonus Armor and Magic\r\n" +
							"Resistance by %f%",
							new double[,] { { 2.5, 5 } },
							null,
							null,
							0,
							250,
							85);
					#endregion
					#region Tough Skin
					mToughSkin =
						new Mastery(
							"Tough Skin",
							treePoint(3, 0, Trees.Defense),
							2,
							"Reduces damage taken from minions and monsters by %f",
							new double[,] { { 1, 2 } },
							null,
							null,
							0,
							310,
							60);
					#endregion
					#region Unyielding
					mUnyielding =
						new Mastery(
							"Unyielding",
							treePoint(0, 1, Trees.Defense),
							1,
							"Melee - Reduces all incoming damage\r\n" + "from champions by 2\r\n" + "Ranged - Reduces all incoming damage\r\n" + "from champions by 1",
							null,
							new Mastery[] { mDefense, mBlock }, 
							new int[] { 4, 2 },
							1,
							200,
							70);
					#endregion
					#region Veteran Scars
					mVeteranScars =
						new Mastery(
							"Veteran Scars",
							treePoint(1, 1, Trees.Defense),
							3,
							"+%f Health",
							new double[,] { { 12, 24, 36 } }, 
							defensePoints,
							new int[] { 4 },
							1,
							200,
							85);
					#endregion
					#region Bladed Armor
					mBladedArmor =
						new Mastery(
							"Bladed Armor",
							treePoint(3, 1, Trees.Defense),
							1,
							"Taking Basic Attack damage from\r\n" + "neutral monsters cause them to bleed,\r\n" + "dealing damage equal to 1% of their\r\n" + "current Health each second\r\n" + "This does not work against lane minions",
							null,
							new Mastery[] { mDefense, mToughSkin },
							new int[] { 4, 2 },
							1,
							280,
							85);
					#endregion
					#region Oppression
					mOppression =
						new Mastery(
							"Oppression",
							treePoint(0, 2, Trees.Defense),
							1,
							"Reduces damage taken by 3% from\r\n" + "enemies that have impaired movement\r\n" + "(slows, snares, taunts, stuns, etc.)",
							null,
							defensePoints,
							new int[] { 8 },
							2,
							200,
							70);
					#endregion
					#region Juggernaut
					mJuggernaut =
						new Mastery(
							"Juggernaut",
							treePoint(1, 2, Trees.Defense),
							1,
							"+3% Maximum Health",
							null,
							new Mastery[] { mDefense, mVeteranScars},
							new int[] { 8, 3 },
							2,
							200,
							70);
					#endregion
					#region Hardiness
					mHardiness =
						new Mastery(
							"Hardiness",
							treePoint(2, 2, Trees.Defense),
							3,
							"+%f Armor",
							new double[,] { { 2, 3.5, 5 } },
							defensePoints,
							new int[] { 8 },
							2,
							200,
							60);
					#endregion
					#region Resistance
					mResistance =
						new Mastery(
							"Resistance",
							treePoint(3, 2, Trees.Defense),
							3,
							"+%f Magic Resist",
							new double[,] { { 2, 3.5, 5 } },
							defensePoints,
							new int[] { 8 },
							2,
							200,
							60);
					#endregion
					#region Perseverance
					mPerseverance =
						new Mastery(
							"Perseverance",
							treePoint(0, 3, Trees.Defense),
							3,
							"Regenerates %f% missing Health every 5\r\n" + "seconds",
							new double[,] { { 1, 2, 3 } },
							defensePoints,
							new int[] { 12 },
							3,
							200,
							70);
					#endregion
					#region Swiftness
					mSwiftness =
						new Mastery(
							"Swiftness",
							treePoint(1, 3, Trees.Defense),
							1,
							"Reduces the effectiveness of slows by\r\n" + "10%",
							null,
							defensePoints,
							new int[] { 12 },
							3,
							200,
							70);
					#endregion
					#region Reinforced Armor
					mReinforcedArmor =
						new Mastery(
							"Reinforced Armor",
							treePoint(2, 3, Trees.Defense),
							1,
							"Reduces damage taken from critical\r\n" + "strikes by 10%",
							null,
							new Mastery[] { mDefense, mHardiness},
							new int[] { 12, 3 },
							3,
							200,
							85);
					#endregion
					#region Evasive
					mEvasive =
						new Mastery(
							"Evasive",
							treePoint(3, 3, Trees.Defense),
							1,
							"Reduces damage taken by 4% from\r\n" + "Area of Effect magic damage",
							null,
							new Mastery[] { mDefense, mResistance },
							new int[] { 12, 3 },
							3,
							200,
							85);
					#endregion
					#region Second Wind
					mSecondWind =
						new Mastery(
							"Second Wind",
							treePoint(0, 4, Trees.Defense),
							1,
							"Increases self-healing, Health Regen\r\n" + "Lifesteal, and Spellvamp by 10% when\r\n" + "below 25% Health",
							null,
							new Mastery[] { mDefense, mPerseverance }, 
							new int[] { 16, 3 },
							4,
							200,
							85);
					#endregion
					#region Tenacious
					mTenacious =
						new Mastery(
							"Tenacious",
							treePoint(1, 4, Trees.Defense),
							4,
							"+%f Armor and %f Magic Resistance for\r\n" + "each nearby enemy champion",
							new double[,] { { 1, 2, 3, 4 }, { 0.5, 1, 1.5, 2} },
							defensePoints,
							new int[] { 16 },
							4,
							200,
							70);
					#endregion
					#region Runic Shield
					mRunicShield =
						new Mastery(
							"Runic Shield",
							treePoint(2, 4, Trees.Defense),
							1,
							"Start the game with a 50 Health shield.\r\n" + "This shield regenerates each time after\r\n" + "respawning",
							null,
							defensePoints,
							new int[] { 16 },
							4,
							200,
							85);
					#endregion
					#region Legendary Guardian
					mLegendaryGuardian =
						new Mastery(
							"Legendary Guardian",
							treePoint(1, 5, Trees.Defense),
							1,
							"Reduces the duration of crowd control\r\n" + "effects by 15%",
							null,
							defensePoints,
							new int[] { 20 },
							5,
							210,
							70);
					#endregion
					#region Add Items to Lists
					defenseMasteries.Add(mBlock);
					defenseMasteries.Add(mRecovery);
					defenseMasteries.Add(mEnchantedArmor);
					defenseMasteries.Add(mToughSkin);
					defenseMasteries.Add(mUnyielding);
					defenseMasteries.Add(mVeteranScars);
					defenseMasteries.Add(mBladedArmor);
					defenseMasteries.Add(mOppression);
					defenseMasteries.Add(mJuggernaut);
					defenseMasteries.Add(mHardiness);
					defenseMasteries.Add(mResistance);
					defenseMasteries.Add(mPerseverance);
					defenseMasteries.Add(mSwiftness);
					defenseMasteries.Add(mReinforcedArmor);
					defenseMasteries.Add(mEvasive);
					defenseMasteries.Add(mSecondWind);
					defenseMasteries.Add(mTenacious);
					defenseMasteries.Add(mRunicShield);
					defenseMasteries.Add(mLegendaryGuardian);
					Masteries.Add(defenseMasteries);
					#endregion
					#endregion
			#region Utility
				#region Phasewalker
					mPhasewalker =
						new Mastery(
							"Phasewalker",
							treePoint(0, 0, Trees.Utility),
							1,
							"Reduces the casting time of Recall by 1\r\n" + "second\r\n\r\n" + "Dominion - Reduces the casting time of\r\n" + "Enhanced Recall by 0.5 seconds",
							null,
							null,
							null,
							0,
							375,
							117);
				#endregion
				#region Fleet Of Foot
					mFleetOfFoot =
						new Mastery(
							"Fleet Of Foot",
							treePoint(1, 0, Trees.Utility),
							3,
							"+%f% Movement Speed",
							new double[,] { { 0.5, 1, 1.5 } }, 
							null,
							null,
							0,
							200,
							85);
				#endregion
				#region Meditation
					mMeditation =
						new Mastery(
							"Meditation",
							treePoint(2, 0, Trees.Utility),
							3,
							"+%f Mana Regen per 5 seconds",
							new double[,] { { 1, 2, 3 } },
							null,
							null,
							0,
							200,
							85);
				#endregion
				#region Scout
				mScout =
					new Mastery(
						"Scout",
						treePoint(3, 0, Trees.Utility),
						1,
						"Increases the cast range of trinket items\r\n" + "by 15%",
						null,
						null,
						null,
						0,
						200,
						85);
				#endregion
				#region Summoner's Insight
					mSummonersInsight =
						new Mastery(
							"Summoner's Insight",
							treePoint(1, 1, Trees.Utility),
							3,
							"Reduces the cooldown of Summoner\r\n" + "Spells by %f%",
							new double[,] { { 4, 7, 10 } }, 
							utilityPoints,
							new int[] { 4 }, 
							1,
							200,
							85);
				#endregion
				#region Strength of Spirit
				mStrengthOfSpirit =
					new Mastery(
						"Strength Of Spirit",
						treePoint(2, 1, Trees.Utility),
						1,
						"+1 Health Regen per 5 seconds for\r\n" + "every 300 maximum Mana",
						null,
						new Mastery[] { mUtility, mMeditation }, 
						new int[] { 4, 3 },
						1,
						200,
						85);
				#endregion
				#region Alchemist
					mAlchemist =
						new Mastery(
							"Alchemist",
							treePoint(3, 1, Trees.Utility),
							1,
							"Increases the duration of potions and\r\n" + "elixers by 10%",
							null, 
							utilityPoints,
							new int[] { 4 },
							1,
							200,
							85);
				#endregion
				#region Greed
					mGreed =
						new Mastery(
							"Greed",
							treePoint(0, 2, Trees.Utility),
							3,
							"+%f Gold every 10 seconds",
							new double[,] { { 0.5, 1, 1.5 } },
							utilityPoints,
							new int[] { 8 },
							2,
							200,
							85);
				#endregion
				#region Runic Affinity
					mRunicAffinity =
						new Mastery(
							"Runic Affinity",
							treePoint(1, 2, Trees.Utility),
							1,
							"Increases the duration of shrine, relic,\r\n" + "quest, and neutral monster buffs by 20%",
							null,
							utilityPoints,
							new int[] { 8 },
							2,
							200,
							85);
				#endregion
				#region Vampirism
					mVampirism =
						new Mastery(
							"Vampirism",
							treePoint(2, 2, Trees.Utility),
							3,
							"+%f% Lifesteal and Spellvamp",
							new double[,] { { 1, 2, 3 } },
							utilityPoints,
							new int[] { 8 },
							2,
							200,
							85);
				#endregion
				#region Culinary Master
					mCulinaryMaster =
						new Mastery(
							"Culinary Master",
							treePoint(3, 2, Trees.Utility),
							1,
							"Health potions are upgraded into\r\n" + "Biscuits that restore an additional 20\r\n" + "Health and 10 Mana instantly upon\r\n" + "consumption",
							null,
							new Mastery[] { mUtility, mAlchemist }, 
							new int[] { 8, 1 },
							2,
							200,
							85);
				#endregion
				#region Scavenger
					mScavenger =
						new Mastery(
							"Scavenger",
							treePoint(0, 3, Trees.Utility),
							1,
							"+1 Gold each time an ally kills a nearby lane minion",
							null, 
							new Mastery[] { mUtility, mGreed }, 
							new int[] { 12, 3 },
							3,
							200,
							85);
				#endregion
				#region Wealth
					mWealth =
						new Mastery(
							"Wealth",
							treePoint(1, 3, Trees.Utility),
							1,
							"+40 Starting Gold",
							null,
							utilityPoints,
							new int[] { 12 },
							3,
							200,
							85);
				#endregion
				#region Expanded Mind
					mExpandedMind =
						new Mastery(
							"Expanded Mind",
							treePoint(2, 3, Trees.Utility),
							3,
							"+%f% increased maximum Mana",
							new double[,] { { 2, 3.5, 5 } },
							utilityPoints,
							new int[] { 12 },
							3,
							200,
							85);
				#endregion
				#region Inspiration
					mInspiration =
						new Mastery(
							"Inspiration",
							treePoint(3, 3, Trees.Utility),
							2,
							"+%f Experience every 10 seconds while\r\n" + "near a higher level allied champion",
							new double[,] { { 5, 10 } },
							utilityPoints,
							new int[] { 12 },
							3,
							200,
							85);
					#endregion
				#region Bandit
					mBandit =
						new Mastery(
							"Bandit",
							treePoint(1, 4, Trees.Utility),
							1,
							"Melee - Grants +15 Gold on champion\r\n" + "kill or assist\r\n" + "Ranged - Grants +3 Gold each time an\r\n" + "enemy champion is attacked. This\r\n" + "cannot trigger on the same champion\r\n" + "more than once every 5 seconds",
							null,
							new Mastery[] { mUtility, mWealth },
							new int[] { 16, 1 },
							4,
							200,
							85);
				#endregion
				#region Intelligence
					mIntelligence =
						new Mastery(
							"Intelligence",
							treePoint(2, 4, Trees.Utility),
							3,
							"+%f% Cooldown Reduction and reduces\r\n" + "the cooldown of Activated Items by %f%",
							new double[,] { { 2, 3.5, 5 }, { 4, 7, 10 } }, 
							utilityPoints,
							new int[] { 16 },
							4,
							200,
							85);
				#endregion
				#region Wanderer
					mWanderer =
						new Mastery(
							"Wanderer",
							treePoint(1, 5, Trees.Utility),
							1,
							"+5% Movement Speed out of combat",
							null,
							utilityPoints,
							new int[] { 20 },
							5,
							200,
							85);
				#endregion
				#region Add Items to Lists
					utilityMasteries.Add(mPhasewalker);
					utilityMasteries.Add(mFleetOfFoot);
					utilityMasteries.Add(mMeditation);
					utilityMasteries.Add(mScout);
					utilityMasteries.Add(mSummonersInsight);
					utilityMasteries.Add(mStrengthOfSpirit);
					utilityMasteries.Add(mAlchemist);
					utilityMasteries.Add(mGreed);
					utilityMasteries.Add(mRunicAffinity);
					utilityMasteries.Add(mVampirism);
					utilityMasteries.Add(mCulinaryMaster);
					utilityMasteries.Add(mScavenger);
					utilityMasteries.Add(mWealth);
					utilityMasteries.Add(mExpandedMind);
					utilityMasteries.Add(mInspiration);
					utilityMasteries.Add(mBandit);
					utilityMasteries.Add(mIntelligence);
					utilityMasteries.Add(mWanderer);
					Masteries.Add(utilityMasteries);
				#endregion
			#endregion
		}

		/// <summary>
		/// Adds all the labels on the form to lists, so that they can be modified for the corrosponding mastery.
		/// </summary>
		private static void labelLists()
		{
			#region Labels
				#region Offense
					offenseLabels.Add(Editor.lblDoubleEdgedSword);
					offenseLabels.Add(Editor.lblFury);
					offenseLabels.Add(Editor.lblSorcery);
					offenseLabels.Add(Editor.lblButcher);
					offenseLabels.Add(Editor.lblExposeWeakness);
					offenseLabels.Add(Editor.lblBruteForce);
					offenseLabels.Add(Editor.lblMentalForce);
					offenseLabels.Add(Editor.lblFeast);
					offenseLabels.Add(Editor.lblSpellWeaving);
					offenseLabels.Add(Editor.lblMartialMastery);
					offenseLabels.Add(Editor.lblArcaneMastery);
					offenseLabels.Add(Editor.lblExecutioner);
					offenseLabels.Add(Editor.lblBladeWeaving);
					offenseLabels.Add(Editor.lblWarlord);
					offenseLabels.Add(Editor.lblArchmage);
					offenseLabels.Add(Editor.lblDangerousGame);
					offenseLabels.Add(Editor.lblFrenzy);
					offenseLabels.Add(Editor.lblDevestatingStrikes);
					offenseLabels.Add(Editor.lblArcaneBlade);
					offenseLabels.Add(Editor.lblHavoc);
					Labels.Add(offenseLabels);
				#endregion
				#region Defense
					defenseLabels.Add(Editor.lblBlock);
					defenseLabels.Add(Editor.lblRecovery);
					defenseLabels.Add(Editor.lblEnchantedArmor);
					defenseLabels.Add(Editor.lblToughSkin);
					defenseLabels.Add(Editor.lblUnyielding);
					defenseLabels.Add(Editor.lblVeteranScars);
					defenseLabels.Add(Editor.lblBladedArmor);
					defenseLabels.Add(Editor.lblOppression);
					defenseLabels.Add(Editor.lblJuggernaut);
					defenseLabels.Add(Editor.lblHardiness);
					defenseLabels.Add(Editor.lblResistance);
					defenseLabels.Add(Editor.lblPerseverance);
					defenseLabels.Add(Editor.lblSwiftness);
					defenseLabels.Add(Editor.lblReinforcedArmor);
					defenseLabels.Add(Editor.lblEvasive);
					defenseLabels.Add(Editor.lblSecondWind);
					defenseLabels.Add(Editor.lblTenacious);
					defenseLabels.Add(Editor.lblRunicShield);
					defenseLabels.Add(Editor.lblLegendaryGuardian);
					Labels.Add( defenseLabels );
				#endregion
				#region Utility
					utilityLabels.Add(Editor.lblPhasewalker);
					utilityLabels.Add(Editor.lblFleetOfFoot);
					utilityLabels.Add(Editor.lblMeditation);                    
					utilityLabels.Add(Editor.lblScout);
					utilityLabels.Add(Editor.lblSummonersInsight);
					utilityLabels.Add(Editor.lblStrengthOfSpirit);
					utilityLabels.Add(Editor.lblAlchemist);                    
					utilityLabels.Add(Editor.lblGreed);
					utilityLabels.Add(Editor.lblRunicAffinity);
					utilityLabels.Add(Editor.lblVampirism);
					utilityLabels.Add(Editor.lblCulinaryMaster);
					utilityLabels.Add(Editor.lblScavenger);
					utilityLabels.Add(Editor.lblWealth);
					utilityLabels.Add(Editor.lblExpandedMind);
					utilityLabels.Add(Editor.lblInspiration);
					utilityLabels.Add(Editor.lblBandit);
					utilityLabels.Add(Editor.lblIntelligence);
					utilityLabels.Add(Editor.lblWanderer);
					Labels.Add(utilityLabels);
				#endregion
					Labels.Add(offenseLabels);
					Labels.Add(defenseLabels);
					Labels.Add(utilityLabels);
			PointLabels = new List<Label>();
			PointLabels.Add( Editor.lblOffensePoints );
			PointLabels.Add( Editor.lblDefensePoints );
			PointLabels.Add( Editor.lblUtilityPoints );
			#endregion
		}

		private static Point treePoint( int offsetX, int offsetY, Trees t )
		{
			switch ( t )
			{
				case Trees.Offense:
					return new Point(offense.X + (spacer.X * offsetX), offense.Y + (spacer.Y * offsetY));
				case Trees.Defense:
					return new Point ( defense.X + ( spacer.X * offsetX ), defense.Y + ( spacer.Y * offsetY ) );
				case Trees.Utility:
					return new Point ( utility.X + ( spacer.X * offsetX ), utility.Y + ( spacer.Y * offsetY ) );
				default:
					return new Point ( offense.X + ( spacer.X * offsetX ), offense.Y + ( spacer.Y * offsetY ) );
			}
		}

		private static Boolean meetsRequirements( Mastery m )
		{
			int index = -1;
			foreach ( Mastery m2 in m.Conditions )
			{
				index = m.Conditions.IndexOf( m2 );
				if ( m2.Level < m.ConditionLevels[index] ) 
				{
					return false;
				}
			}
			return true;
		}

		private static Point getToolTipPoint ( Mastery m ) 
		{
			Point topLeft     = new Point( Editor.MasteryTree.Location.X + m.Rectangle.X + m.Rectangle.Width, Editor.MasteryTree.Location.Y + m.Rectangle.Y + m.Rectangle.Height );
			Point bottomRight = new Point( Editor.MasteryTree.Location.X + m.Rectangle.X + m.Rectangle.Width + m.Width, Editor.MasteryTree.Location.Y + m.Rectangle.Y + m.Rectangle.Height + m.Height );
			Point rPoint      = topLeft;
			if ( bottomRight.X >= Editor.Width  ) { rPoint.X = rPoint.X - Editor.pnlTooltip.Width  - m.Rectangle.Width;  }
			if ( bottomRight.Y >= Editor.Height ) { rPoint.Y = rPoint.Y - Editor.pnlTooltip.Height - m.Rectangle.Height; }
			return rPoint;
		}

		private static void updateBuildCode()
		{
			string s = "";
			foreach( List<Mastery> a in Masteries )
			{
				foreach ( Mastery m in a )
				{
					s += m.Level.ToString();
				}
				s += "\r\n";
			}
			Editor.edtBuildCode.Text = s;
		}

		private void buildLoad( string s )
		{
			int i = 0;
			int count = 0;
			int total = 0;
			Regex regex = new Regex( "\r?\n" );
			string offenseString = regex.Split(s)[0];
			string defenseString = regex.Split(s)[1];
			string utilityString = regex.Split(s)[2];
			foreach( char c in offenseString.ToCharArray() )
			{
				offenseMasteries[i].Level = Convert.ToInt32( c.ToString() );
				offenseLabels[i].Text = offenseMasteries[i].Level + " / " + offenseMasteries[i].MaxLevel;
				count += offenseMasteries[i].Level;
				i++;
			}
			mOffense.Level = count;
			total += count;
			count = 0;
			i = 0;
			foreach( char c in defenseString.ToCharArray() )
			{
				defenseMasteries[i].Level = Convert.ToInt32( c.ToString() );
				defenseLabels[i].Text = defenseMasteries[i].Level + " / " + defenseMasteries[i].MaxLevel;
				count += defenseMasteries[i].Level;
				i++;
			}
			mDefense.Level = count;
			total += count;
			count = 0;
			i = 0;
			foreach( char c in utilityString.ToCharArray() )
			{
				utilityMasteries[i].Level = Convert.ToInt32( c.ToString() );
				utilityLabels[i].Text = utilityMasteries[i].Level + " / " + utilityMasteries[i].MaxLevel;
				count += utilityMasteries[i].Level;
				i++;
			}
			mUtility.Level = count;
			total += count;
			Editor.lblOffensePoints.Text = Editor.lblOffensePoints.Tag + mOffense.Level.ToString();
			Editor.lblDefensePoints.Text = Editor.lblDefensePoints.Tag + mDefense.Level.ToString();
			Editor.lblUtilityPoints.Text = Editor.lblUtilityPoints.Tag + mUtility.Level.ToString();
			Editor.lblPointsRemaining.Text = Editor.lblPointsRemaining.Tag + ( 30 - total ).ToString();
			PointsRemaining = 30 - total;
		}

		private bool wontAffectOtherMasteries( Mastery compare )
		{
			List<Mastery> tree = getTree( compare );
			Mastery mTree = getTreeMastery( compare );
			int index = 0;
			int count = pointsInTree( tree );
			foreach ( Mastery m in tree )
			{
				if ( m.Conditions.Count > 0 && m.ConditionLevels != null && m.Level > 0 && m != compare )
				{
					if ( m.Conditions.Contains( mTree ) )
					{
						index = m.Conditions.IndexOf( mTree );
						//MessageBox.Show( "Previous Row Count:" + ( getPreviousRowCount( m ) - 1 ).ToString() + "\r\nRequired Tree Level:" + m.ConditionLevels[index].ToString() );
						if( (mTree.Level - 1 ) < m.ConditionLevels[index] )
						{
							return false;
						} else if( ( getPreviousRowCount( m ) - 1 ) < m.ConditionLevels[index] && m.Row > compare.Row ) {
							return false;
						}
					} else if ( m.Conditions.Contains( compare ))
					{
						index = m.Conditions.IndexOf( compare );
						if( (compare.Level - 1) < m.ConditionLevels[index] )
						{
							return false;
						}
					}
				}
			}
			return true;
		}

		private int getPreviousRowCount( Mastery m )
		{
			int r = 0;
			foreach ( Mastery m2 in getTree( m ) )
			{
				if ( m2.Row < m.Row )
				{
					r += m2.Level;
				}
			}
			return r;
		}

		private List<Mastery> getTree( Mastery m )
		{
			if( offenseMasteries.Contains( m ) ){ return offenseMasteries; }
			if( defenseMasteries.Contains( m ) ){ return defenseMasteries; }
			if( utilityMasteries.Contains( m ) ){ return utilityMasteries; }
			return null;
		}

		private Mastery getTreeMastery( Mastery m )
		{
			if( offenseMasteries.Contains( m ) ){ return mOffense; }
			if( defenseMasteries.Contains( m ) ){ return mDefense; }
			if( utilityMasteries.Contains( m ) ){ return mUtility; }
			return null;
		}

		private int pointsInTree( Trees t )
		{
			int i = 0;
			switch ( t )
			{
				case Trees.Offense:
					foreach ( Mastery m in offenseMasteries )
					{
						i += m.Level;
					}
					return i;
				case Trees.Defense:
					foreach ( Mastery m in defenseMasteries )
					{
						i += m.Level;
					}
					return i;
				case Trees.Utility:
					foreach ( Mastery m in utilityMasteries )
					{
						i += m.Level;
					}
					return i;
				default:
					return -1;
			}
		}

		private int pointsInTree( Mastery m )
		{
			int i = 0;
			List<Mastery> list = new List<Mastery>();
			if ( m == mOffense ) list = offenseMasteries;
			if ( m == mDefense ) list = defenseMasteries;
			if ( m == mUtility ) list = utilityMasteries;

			foreach ( Mastery m2 in list )
			{
				i += m2.Level;
			}
			return i;
		}

		private int pointsInTree( List<Mastery> m )
		{
			int i = 0;
			foreach ( Mastery m2 in m )
			{
				i += m2.Level;
			}
			return i;
		}

		private void BuildEditor_Load(object sender, EventArgs e)
		{
			bgwChecker.RunWorkerAsync();
		}
	}
}
